﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyOCR
{
    [StructLayout(LayoutKind.Sequential)]
    public struct KeyMSG
    {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    class HookHandel
    {
        public event KeyEventHandler KeyDownEvent;

        // 安装钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        // 卸载钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);
        // 继续下一个钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
        // 取得当前线程编号
        [DllImport("kernel32.dll")]
        static extern int GetCurrentThreadId();

        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

        static int hKeyboardHook = 0;//如果hKeyboardHook不为0则说明钩子安装成功
        HookProc KeyboardHookProcedure;

        private const int WM_KEYUP = 0x101;//KEYUP

        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr IParam)
        {
            KeyMSG m = (KeyMSG)Marshal.PtrToStructure(IParam, typeof(KeyMSG));
            Keys keyData = (Keys)m.vkCode;

            if (nCode >= 0 && KeyDownEvent != null && keyData == Keys.F4 && wParam == WM_KEYUP)
            {
                
                KeyEventArgs e = new KeyEventArgs(keyData);
                KeyDownEvent(this, e);
                return 1;
            }

            return CallNextHookEx(hKeyboardHook, nCode, wParam, IParam);
        }

        //钩子安装
        public void HookStart()
        {
            if (hKeyboardHook == 0)//如果hKeyboardHook==0,钩子安装失败
            {
                //创建HookProc实例
                KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                //设置线程钩子
                //hKeyboardHook = SetWindowsHookEx(2, KeyboardHookProc, IntPtr.Zero, GetCurrentThreadId());

                hKeyboardHook = SetWindowsHookEx(13, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);//全局钩子安装

                if (hKeyboardHook == 0)
                {
                    //终止钩子
                    throw new Exception("安装钩子失败");
                }
            }
        }

        //钩子卸载
        public void HookStop()
        {
            bool retKeyboard = true;
            if (hKeyboardHook != 0)
            {
                retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                hKeyboardHook = 0;
            }
            if (!retKeyboard)
                throw new Exception("钩子卸载失败");

        }


    }
}
